<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="umsroot.css">
<TITLE>
Waiting for Instantiation
</TITLE>
</HEAD>
<BODY >
<A HREF="umsroot117.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot119.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc261">18.1</A>&nbsp;&nbsp;Waiting for Instantiation</H2>
Goals that are to be woken when one or more variables become
instantiated use the <B>inst</B> list.
For instance, a predicate <B>freeze(Term, Goal)</B> which
delays and is woken as soon as any variable in <B>Term</B>
becomes instantiated can be implemented as follows:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
freeze(Term, Goal) :-
    suspend(Goal, 3, Term-&gt;inst).
</PRE></BLOCKQUOTE>
or equivalently by
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
freeze(Term, Goal) :-
    make_suspension(Goal, 3, Susp),
    insert_suspension(Term, Susp, inst of suspend, suspend).
</PRE></BLOCKQUOTE>
When it is called with a nonground term, it produces a delayed goal
and when one variable is instantiated, the goal is woken:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
[eclipse 2]: freeze(X, write(hello)).

X = X

Delayed goals:
        write(hello)
yes.
[eclipse 3]: freeze(p(X, Y), write(hello)), X=Y.

X = X
Y = X

Delayed goals:
        write(hello)
yes.
[eclipse 4]: freeze(p(X, Y), write(hello)), Y=1.
hello
X = X
Y = 1
yes.
</PRE></BLOCKQUOTE>
However, if its argument is ground, it will still produce
a suspended goal which may not be what we expect:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
[eclipse 5]: 8.
freeze(a, write(hello)).


Delayed goals:
        write(hello)
yes.
</PRE></BLOCKQUOTE>
To correct this problem, we can test this condition separately:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
freeze(Term, Goal) :-
    nonground(Term),
    !,
    suspend(Goal, 3, Term-&gt;inst).
freeze(_, Goal) :-
    call(Goal).
</PRE></BLOCKQUOTE>
and get the expected results:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
[eclipse 8]: freeze(a, write(hello)).
hello
yes.
</PRE></BLOCKQUOTE>
Another possibility is to wait until a term becomes ground,
i.e. all its variables become instantiated.
In this case, it is not necessary to attach the suspension
to <I>all</I> variables in the term.
The <B>Goal</B> has to be called when the last variable in <B>Term</B>
is instantiated, and so we can pick up any variable and
attach the suspension to it.
We may then save some unnecessary waking when other variables
are instantiated before the selected one.
To select a variable from the term,
we can use the predicate <A HREF="../bips/kernel/termmanip/term_variables-2.html"><B>term_variables/2</B></A><A NAME="@default1054"></A> which extracts
all variables from a term.
However, when we already have all variables available, we can in fact
dispose of <B>Term</B> which may be huge and have
a complicated structure.
Instead, we pick up one variable from the list until
we reach its end:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
wait_for_ground(Term, Goal) :-
    term_variables(Term, VarList),
    wait_for_var(VarList, Goal).

wait_for_var([], Goal) :-
    call(Goal).
wait_for_var([X|L], Goal) :-
    (var(X) -&gt;
        suspend(wait_for_var([X|L], Goal), 3, X-&gt;inst)
    ;
    nonground(X) -&gt;
        term_variables(X, Vars),
        append(Vars, L, NewVars),
        wait_for_var(NewVars, Goal)
    ;
        wait_for_var(L, Goal)
    ).
</PRE></BLOCKQUOTE>
<HR>
<A HREF="umsroot117.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot119.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
